#include"util.hpp"

using namespace cloudBackup;
long int cloudBackup::FileUtil::FileSize()
{
    struct stat st;
    if(stat(_filename.c_str(),&st)<0)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"获取文件大小error"<<endl;
        return -1;
    }
    return st.st_size;
}

time_t cloudBackup::FileUtil::LastModFile()
{
    struct stat st;
    if(stat(_filename.c_str(),&st)<0)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"获取文件最新修改时间error"<<endl;
        return -1;
    }
    return st.st_mtime;
}

time_t cloudBackup::FileUtil::LastAccFile()
{
    struct stat st;
    if(stat(_filename.c_str(),&st)<0)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"获取文件最新访问时间error"<<endl;
        return -1;
    }
    return st.st_atime;
}

string cloudBackup::FileUtil::FileName()
{
    int pos=_filename.rfind("/");
    if(pos!=string::npos)
    {
        return _filename.substr(pos+1);
    }
    return _filename;
}

bool cloudBackup::FileUtil::GetPosLen(string *body, size_t pos, size_t len)
{
    //读取文件内容
    size_t fileSize=this->FileSize();
    if(len+pos > fileSize)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"获取文件内容超出文件大小"<<endl;
        return false;
    }
    ifstream inFile;
    inFile.open(_filename,std::ios::binary);
    if(inFile.is_open()==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"打开文件error"<<endl;
        return false;
    }
    inFile.seekg(pos,ios_base::beg);
    body->resize(len);
    inFile.read(&(*body)[0],len);
    if(inFile.good()==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"读取文件error"<<endl;
        inFile.close();
        return false;
    }
    inFile.close();
    return true;
}

bool cloudBackup::FileUtil::GetContent(string *body)
{
    size_t fileSize=this->FileSize();
    return GetPosLen(body,0,fileSize);
}

bool cloudBackup::FileUtil::SetContent(const string &body)
{
    ofstream outFile;
    outFile.open(_filename,std::ios::binary);
    if(outFile.is_open()==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"打开文件error"<<endl;
        return false;
    }
    outFile.write(&body[0],body.size());
    if(outFile.good()==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"写入文件error"<<endl;
        outFile.close();
        return false;
    }
    outFile.close();
    return true;
}

bool cloudBackup::FileUtil::Compress(const string &packname)
{
    string body;
    if(this->GetContent(&body)==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"压缩包读取数据error"<<endl;
        return false;
    }
    string packed=bundle::pack(bundle::LZIP,body);
    FileUtil fu(packname);
    if(fu.SetContent(packed)==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"压缩包写入数据error"<<endl;
        return false;
    }
    return true;
}

bool cloudBackup::FileUtil::UnCompress(const string &packname)
{
    //读取当前压缩包的内容
    //对压缩包的数据进行解压
    //将解压的数据写入新文件
    string body;
    if(this->GetContent(&body)==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"解压缩包读取数据error"<<endl;
        return false;
    }
    string unpacked=bundle::unpack(body);
    FileUtil fu(packname);
    if(fu.SetContent(unpacked)==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"解压缩包写入数据error"<<endl;
        return false;
    }
    return true;
}

bool cloudBackup::FileUtil::Exists()
{
    if(fs::exists(_filename)==false)
        return false;
    return true;
}

bool cloudBackup::FileUtil::CreateDir()
{
    if(this->Exists()) return true;
    return fs::create_directory(_filename);
}

bool cloudBackup::FileUtil::ScanDir(vector<string> *arry)
{
    for(auto& f : fs::directory_iterator(_filename))
    {
        if(fs::is_directory(f)==true)
            continue;
        arry->push_back(fs::path(f).string());
    }
    return true;
}

bool cloudBackup::JsonUtil::Serialize(const Json::Value &root, string *str)
{
    Json::StreamWriterBuilder  swb;
    shared_ptr<Json::StreamWriter> ptr(swb.newStreamWriter());
    ostringstream os;
    if(ptr->write(root,&os)!=0)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"json 序列化error"<<endl;
        return false;
    }
    *str=os.str();
    cout<<__FILE__<<"-"<<__LINE__<<":"<<"json 序列化成功"<<endl;
    return true;
}

bool cloudBackup::JsonUtil::UnSerialize(const string &str, Json::Value *root)
{
    Json::CharReaderBuilder crb;
    shared_ptr<Json::CharReader> ptr(crb.newCharReader());
    string err;
    int ret=ptr->parse(str.c_str(),str.c_str()+str.size(),root,&err);
    if(ret==false)
    {
        cout<<__FILE__<<"-"<<__LINE__<<":"<<"json 反序列化error"<<endl;
        return false;
    }
    return true;
}
